package com.ruiysoft.service.order.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruiysoft.controller.order.vo.OrderDeliverVo;
import com.ruiysoft.controller.order.vo.OrderModifyVo;
import com.ruiysoft.controller.order.vo.SplitOrderVO;
import com.ruiysoft.entity.ModelApiResponse;
import com.ruiysoft.entity.order.OrderMain;
import com.ruiysoft.pub.core.Result;
import com.ruiysoft.pub.entity.PageInfo;
import com.ruiysoft.service.order.IOrderShopService;
import com.ruiysoft.service.order.IOrderWechatService;
import com.ruiysoft.service.order.bean.OrderDto;
import com.ruiysoft.service.order.consts.OrderDBStatusEnum;
import com.ruiysoft.service.order.facade.OrderShopFacade;
import com.ruiysoft.service.order.util.OrderCheckUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Date : 2018/11/27
 *
 * @author WenJialu
 */
@Service
public class OrderShopServiceImpl implements IOrderShopService {
	private static Logger logger = LoggerFactory.getLogger(OrderShopServiceImpl.class);

	@Resource
	OrderShopFacade oShopFacade;
	@Resource
	IOrderWechatService orderWechatService;
	@Resource
	OrderCheckUtil orderCheckUtil;

	/**
	 * 订单查询
	 *
	 * @param shopId
	 * @param status
	 * @param pageStart
	 * @param pageSize
	 * @return
	 */
	@Override
	public PageInfo<OrderDto> findOrders(Long shopId, Set<Integer> status, Integer pageStart, Integer pageSize) {
		//获取订单主表列表
		IPage<OrderMain> orderMainsPage = oShopFacade.getOrdersPage(shopId, status, pageStart, pageSize);
			List<OrderDto> orderDtos = Optional.ofNullable(orderMainsPage.getRecords())
					.map(os ->
							os.stream()
									.map(o -> orderWechatService.findOrderWithDetailByOrderNo(o.getOrderNo()))
									.collect(Collectors.toList())
			).orElse(Collections.emptyList());

		return new PageInfo<>(orderDtos, pageStart, pageSize, orderMainsPage.getTotal());

		/*if (!orderMainsPage.getRecords().isEmpty()) {
//			List<OrderDto> orderDtos = orderMainsPage.getRecords().stream().map(orderMain -> orderWechatService.findOrderWithDetailByOrderNo(orderMain.getOrderNo())).collect(Collectors.toList());
			return new PageInfo<>(orderDtos, pageStart, pageSize, orderMainsPage.getTotal());
		} else {
			return new PageInfo<>();
		}*/
	}

	/**
	 * 待发货订单
	 *
	 * @param shopId
	 * @param pageStart
	 * @param pageSize
	 * @return
	 */
	@Override
	public PageInfo<OrderDto> findOrdersWaitingDelivering(Long shopId, Integer pageStart, Integer pageSize) {
		return findOrders(shopId, Collections.singleton(OrderDBStatusEnum.SHOP_CONFIRMED_WATTING_FOR_DELIVER.getCode()), pageStart, pageSize);
	}


	@Override
	public OrderDto findOrder(Long shopId, String orderNo) {
		OrderDto orderDto = orderWechatService.findOrderWithDetailByOrderNo(shopId,orderNo);
		if(!shopId.equals(orderDto.getOrderMain().getShopId())){
			throw new RuntimeException("非法订单查询.");
		}
		return orderDto;
	}

	/**
	 * 只允许修改"未支付"状态订单的金额
	 * 关于金额的逻辑，请参考OrderAssembleFacade.assembleOrderMain()
	 * @param shopID
	 * @param modifyVo
	 * @return
	 */
	@Override
	public Result updateOrderMoney(Long shopID, OrderModifyVo modifyVo) {
		OrderDto orderDto = findOrder(shopID,modifyVo.getOrderNo());
		if(!OrderDBStatusEnum.CUSTOMER_CONFIRMED_WAITING_FOR_PAYMENT.getCode().equals(orderDto.getOrderMain().getStatus())){
			//如果订单状态不等于"待支付"，则异常
			throw new RuntimeException("订单状态非\"待支付\",不可修改订单.");
		}
		OrderMain orderMain = orderDto.getOrderMain();
		OrderModifyVo.OrderModifyMoneyTypeEnum modifyType = OrderModifyVo.OrderModifyMoneyTypeEnum.valueOf(modifyVo.getAmountType());
		switch (modifyType){
			case orderMainMoney:
				orderMain.setTotalAmount(modifyVo.getFinalAmount());
				break;
			case orderLogisticMoney:
				orderMain.setFreight(modifyVo.getFinalAmount());
				break;
		}
		Long receivableAmount = Math.addExact(orderMain.getTotalAmount(),orderMain.getFreight());
		orderMain.setReceivableAmount(receivableAmount);
		//Todo,订单修订需要1、记录历史；2、必要的审核确认
		return oShopFacade.updateOrderMoney(shopID,orderMain);
	}

	/**
	 * 发货
	 * TODO MQ
	 * @param orderDeliverVo
	 * @return
	 */
	@Override
	@Transactional
	public Result orderDeliver(Long shopId,OrderDeliverVo orderDeliverVo) {
		Result result = orderCheckUtil.checkOrderDeliver(orderDeliverVo);
		if (result.isSuccess()) {
			result =  oShopFacade.orderDeliver(shopId,orderDeliverVo);
		}
		if(logger.isDebugEnabled()){
			logger.debug("order deliver:{}", JSON.toJSONString(result));
		}
		return result;
	}

	@Override
	public Result shopOrderSplit(Long currShopId, List<SplitOrderVO> splitOrderVOS) {
//        Result result = orderCheckUtil.checkOrderDeliver(orderDeliverVo);
//        if (result.isSuccess()) {
        Result result =  oShopFacade.shopOrderSplit(currShopId,splitOrderVOS);
//        }
        if(logger.isDebugEnabled()){
            logger.debug("order deliver:{}", JSON.toJSONString(result));
        }
        return result;
	}

	@Override
	public Result<ModelApiResponse> shopOrderMergePost(Long currShopId, SplitOrderVO splitOrderVOS) {
		Result result =  oShopFacade.shopOrderMergePost(currShopId,splitOrderVOS);
		if(logger.isDebugEnabled()){
			logger.debug("order deliver:{}", JSON.toJSONString(result));
		}
		return result;
	}
}
